package com.xinggq.auth.service.controller;

import com.xinggq.auth.api.dto.login.LoginRequest;
import com.xinggq.auth.api.dto.login.LoginResponse;
import com.xinggq.auth.api.dto.token.RefreshTokenRequest;
import com.xinggq.auth.api.itf.LoginManagerApi;
import com.xinggq.common.constant.AuthConstants;
import com.xinggq.auth.service.service.LoginManagerService;
import com.xinggq.auth.service.service.TokenManagerService;
import com.xinggq.common.CommonResult;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

/**
 * 认证控制器
 * 提供用户登录、注册、刷新令牌等认证相关接口
 *
 * @author xinggq
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/auth/login")
@RequiredArgsConstructor
public class LoginManagerController implements LoginManagerApi {

  private final LoginManagerService authService;
  private final TokenManagerService tokenManagerService;

  @Override
  @PostMapping("/log-in")
  @Operation(summary = "用户登录")
  public CommonResult<LoginResponse> login(@Valid @RequestBody LoginRequest loginRequest) {
    log.info("用户登入请求：{}", loginRequest.getUsername());
    LoginResponse response = authService.login(loginRequest);
    return CommonResult.ok(response);
  }

  /**
   * 用户登出
   * 从Authorization头中解析Bearer Token；可选读取Refresh-Token头并一并撤销。
   */
  @Override
  @PostMapping("/log-out")
  @Operation(summary = "用户登出")
  public CommonResult<Void> logout(
      @RequestHeader(value = AuthConstants.HEADER_AUTHORIZATION, required = false) String authorization,
      @RequestHeader(value = AuthConstants.HEADER_REFRESH_TOKEN, required = false) String refreshToken) {
    String accessToken = null;
    if (StringUtils.isNotBlank(authorization) && authorization.startsWith(AuthConstants.BEARER_PREFIX)) {
      accessToken = authorization.substring(AuthConstants.BEARER_PREFIX.length()).trim();
    }

    // 无token也返回成功，保持幂等
    if (StringUtils.isNotBlank(accessToken) && StringUtils.isNotBlank(refreshToken)) {
      log.info("登出请求无任何令牌，直接返回成功");
      return CommonResult.ok();
    }

    try {
      // 撤销访问令牌（若存在）
      if (StringUtils.isNotBlank(accessToken)) {
        authService.logout(accessToken);
      }
      // 撤销刷新令牌（若存在）
      if (StringUtils.isNotBlank(refreshToken)) {
        tokenManagerService.revokeRefreshToken(refreshToken);
      }
      return CommonResult.ok();
    } catch (Exception e) {
      log.error("用户登出失败", e);
      // 为保证幂等与前端体验，仍返回成功，但记录错误日志
      return CommonResult.ok();
    }
  }

  @Override
  @PostMapping("/refresh")
  @Operation(summary = "刷新访问令牌", description = "使用刷新令牌获取新的访问令牌")
  public CommonResult<LoginResponse> refreshToken(@Valid @RequestBody RefreshTokenRequest refreshTokenRequest) {
    log.info("刷新令牌请求");
    LoginResponse response = authService.refreshToken(refreshTokenRequest);
    return CommonResult.ok(response);
  }
}